#pragma once

/*房间管理类*/

#include "GameRoom.hpp"
#include "Common.hpp"

using Room_ptr = std::shared_ptr<GameRoom>;
class RoomManager
{
private:
    // 房间id分配器
    LL _dispatch_id;
    std::mutex _mtx;
    // 数据操作句柄
    db::UserInfo *_table_user;
    // 在线用户管理句柄
    OnlineManager *_online_manager;
    // 房间id与房间对象的映射关系
    std::unordered_map<LL, Room_ptr> _rooms;
    // 用户id与房间id的映射关系
    std::unordered_map<LL, LL> _findRoomByUser;
    // 过滤敏感词
    util::Trie _trie;
public:
    RoomManager(db::UserInfo *table_user, OnlineManager *online_manager)
        : _dispatch_id(1),
          _table_user(_table_user),
          _online_manager(online_manager)
    {
    }
    ~RoomManager()
    {
    }
    // 创建房间并添加到_rooms中
    Room_ptr CreateRoom(LL uid1, LL uid2)
    {
        //GetConnByHail内部时线程安全的
        if (_online_manager->GetConnByHail(uid1).first == false || _online_manager->GetConnByHail(uid2).first == false)
        {
            LOG(DEBUG, "用户:%lu或用户:%lu已离开大厅,无法创建房间\n", uid1, uid2);
            return nullptr;
        }
        // 分配房间id
        std::unique_lock<std::mutex> lock(_mtx);
        // 创建房间
        Room_ptr room = std::make_shared<GameRoom>(_dispatch_id, _table_user, _online_manager, &_trie);
        room->SetBlackId(uid1);
        room->SetWhiteId(uid2);
        // 管理
        _rooms.insert({_dispatch_id, room});
        _findRoomByUser.insert({uid1, _dispatch_id});
        _findRoomByUser.insert({uid2, _dispatch_id});
         ++_dispatch_id;
        return room;
    }

    // 查找房间
    Room_ptr FindRoomByRid(LL room_id)
    {
        std::unique_lock<std::mutex> lock(_mtx);
        auto iter = _rooms.find(room_id);
        if (iter == _rooms.end())
        {
            return nullptr;
        }
        return iter->second;
    }
    Room_ptr FindRoomByUid(LL uid)
    {
        std::unique_lock<std::mutex> lock(_mtx);
        auto user_iter = _findRoomByUser.find(uid);
        if (user_iter == _findRoomByUser.end())
        {
            return nullptr;
        }
        LL room_id = user_iter->second;
        auto room_iter = _rooms.find(room_id);
        if (room_iter == _rooms.end())
        {
            return nullptr;
        }
        return room_iter->second;
    }

    // 销毁房间
    void RemoveRoom(LL room_id)
    {
        // 销毁
        Room_ptr room = FindRoomByRid(room_id);
        if(room == nullptr) return;
        LL uid1 = room->BlackId();
        LL uid2 = room->WhiteId();
        std::unique_lock<std::mutex> lock(_mtx);
        _rooms.erase(room_id);
        _findRoomByUser.erase(uid1);
        _findRoomByUser.erase(uid2);
    }
    // 移除用户
    void RemoveUser(LL uid)
    {
        Room_ptr room = FindRoomByUid(uid);
        if(room == nullptr)
        {
            LOG(DEBUG,"房间不存在\n");
            return;
        }
        room->ExitRoom(uid);
        if ( room->PlayCount() != 0)
        {
            LOG(DEBUG, "房间人数不为0,无法销毁房间,roomid = %lu\n", room->RoomId());
            return;
        }
        RemoveRoom(room->RoomId());
    }
};
